/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MortgageCore;
import simframe.simulation.*;
import java.io.*;
import java.util.*;
import java.sql.Date;
import data.LocalData;

/**
 *
 * @author karakots
 */
public class HouseMarket extends SimObject implements iPropertyMarket, iGoverned {

    public static final Swarm.SwarmAction<HouseMarket> newDay = new Swarm.SwarmAction<HouseMarket>() {
        public synchronized void exec(HouseMarket hm) {
            hm.newDay();
        }
    };

    protected Map<String, List<Double>> usHomePrices = new HashMap<String, List<Double>>();
    // kep track of quarter so we can access the correct housing price data
    private int quarterNum;
    private int dayOfQuarter;
    private int numQuartersData;
    private int dataQuarter;
    //String  usHomePriceHistoryStartDate;
    // hack alert! there must be a cleaner way to do this!
    //Date tempDate = new Date(0);
    //Date usHomePriceStartDate = tempDate.valueOf("1991-01-01");
    private int numHomesSold;
    private int numHomesBought;

    public HouseMarket() throws IOException {
        loadHousingProceData();
        reset();
    }

 private void loadHousingProceData() throws IOException {
        InputStream in_stream = LocalData.GetInputStream(LocalData.Input.US_HOUSE_PRICES);
        InputStreamReader is_reader = new InputStreamReader(in_stream);
        BufferedReader reader = new BufferedReader(is_reader);
        String line;
        while ((line = reader.readLine()) != null) {
            String[] lineParse;
            lineParse = line.split(",");
            List<Double> prices = new ArrayList<Double>();
            // get the price data
            int numDataPoints = lineParse.length;
            numQuartersData = numDataPoints;
            for (int j = 1; j < numDataPoints; j++) {
                prices.add(Double.parseDouble(lineParse[j]));
            }
            usHomePrices.put(lineParse[0], prices);
        }
        reader.close();
        is_reader.close();
        in_stream.close();
    }

    public House getHouseToBuy(String state, double hq) {
        House house = new House();
        house.setHouseQ(hq);
        double price = getCurrentHousePrice(state, hq);
        house.setPurchasePrice(price);
        return house;
    }

    public double getCurrentValue(String state, double hq) {
        return getCurrentHousePrice(state, hq);
    }

    public double getRent(String state, double incomePctMedian) {
       return (getCurrentHousePrice(state, incomePctMedian) / 180);
    }

    private double getCurrentHousePrice(String state, double hq) {
        double price = usHomePrices.get(state).get(dataQuarter);
        // no house will cost more than 70% below the average
        double priceFactor = hq;
        if (hq < 0.7)
            priceFactor = 0.7;
        else if (hq > 1.0)
            priceFactor = Math.sqrt(hq);
        return (price * priceFactor * 1000);
    }

    public void homeSold() {
        numHomesSold++;
    }

    public void homeBought() {
        numHomesBought++;
    }

    private void newDay() {
       dayOfQuarter++;
       if (dayOfQuarter >= 90) {
           quarterNum++;
           dayOfQuarter =1;
       }
        // we don't want to go off the end of the data
        if (quarterNum > (numQuartersData-2))
            dataQuarter = numQuartersData - 2;
        else
            dataQuarter = quarterNum;
    }


    // SimObject required methods
    public void reset() {
        quarterNum = 0;
        dayOfQuarter = 0;
        numHomesSold = 0;
        numHomesBought = 0;
    }

    public boolean dead() {
        return false;
    }




    // Property Market Interface
    public void houseOffer(House house, HouseBidAsk ask) {
    }
    public void houseRequest(HouseBidAsk bid) {
    }



    // iGoverned Interface
    public void updateRegsAndExternals(Regulations regs, Externals ext) {
    }

}
